#ifndef Clipper_First
#define Clipper_First
#ifdef __GNUG__
#pragma interface
#endif

#include "VObject.h"

enum ClipperFlags {
	eClipperDefault  = eVObjDefault,
	eClipperLast     = eVObjLast+0
};

class Clipper: public VObject {
public:
	MetaDef(Clipper);
	Clipper(VObject *vp= 0, const Point &minsize= gPoint_1, int id= cIdNone,
								Ink *bg= 0);
	~Clipper();
	void SetDeleteVop(bool dv);
	void Open(bool mode= TRUE);
	void SetContainer(VObject*);
	Metric GetMinSize();
	void SetShift(const Point &s);
	Point GetShift();
	void SetMinExtent(const Point &e);
	const Point &GetMinExtent();
	void Focus();
	void Enable(bool b= TRUE, bool redraw= TRUE);
	VObject *Detect(BoolFun find, void *arg);
	void SetBgInk(Ink *);
	Ink *GetBgInk();
	void ScaleUp(Point &p);
	void ScaleDown(Point &p);
	void SetZoom(float z);
	float GetZoom();
		
	//---- drawing ------------------------
	void DrawInner(Rectangle, bool);
        void DrawInFocus(FeedbackFunc, Command*, const Point &ap,
                                                        const Point &pp, bool);
	void Feedback(Command*, const Point &ap, const Point &pp, bool);
		
	//---- event handling -----------------
	Command *DispatchEvents(Point lp, Token &t, Clipper *cl);
	Point ContainerPoint(Point p);
	bool TrackOnce(Command**, TrackPhase, Point, Point, Point);
	Command *TrackInContent(Point, Token, Command*);
	void SendDown(int, int, void*);
	void Control(int, int, void*);
	void ReadEvent(Token &t);

	//---- resize -------------------------
	void SetExtent(Point e);
	void SetOrigin(Point at);
	void Normalize();
	void ExtentChanged(VObject *what);

	//---- views --------------------------
	void Add(VObject*);
	VObject *Remove(VObject*);
	void ViewSizeChanged();
	Point GetViewSize();
	Rectangle GetViewedRect();
	VObject *GetViewedVObject();
	void InvalidateViewRect(Rectangle r);

	//---- scrolling ----------------------
	const Point &GetRelOrigin();
	virtual Point AutoScroll(Point);
	virtual void Scroll(int mode, Point scroll, bool redraw= TRUE);
	void RevealRect(Rectangle, Point);
	void RevealAlign(Rectangle r, VObjAlign al= VObjAlign(eVObjHLeft+eVObjVTop));
	virtual void ConstrainScroll(Point *newOrigin);
	Point CalcScrollAmount(int mode, const Point &scr, const Rectangle &r);

	//---- input/output --------------------
	OStream& PrintOn(OStream&);
	IStream& ReadFrom(IStream&);

	//---- inspecting ----------------------
	void InspectorId(char *buf, int sz);
	void CollectParts(Collection*);

protected:
	Point Offset();
	void FeedbackOnce(Command *tracker, const Point &ap, const Point &pp,
							bool turniton);

protected:
	Point minExtent, relOrigin, shift;
	float scale;
	VObject *vop;                          // the VObject I show
	Ink *bgcolor;
	bool deleteVop;
};

inline void Clipper::SetDeleteVop(bool dv)
	{ deleteVop= dv; }
inline Point Clipper::Offset()
	{ return contentRect.origin - relOrigin - shift; }
inline void Clipper::SetShift(const Point &s)
	{ shift= s; }
inline Point Clipper::GetShift()
	{ return shift; }
inline const Point &Clipper::GetMinExtent()
	{ return minExtent; }
inline float Clipper::GetZoom()
	{ return scale; }
inline VObject *Clipper::GetViewedVObject()
	{ return vop; }
inline const Point &Clipper::GetRelOrigin()
	{ return relOrigin; }

#endif

